package com.fingard.dsp.bank.directbank.cib03;

import com.fingard.common.utils.json.JSONUtils;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;
import com.fingard.util.DEHelper;
import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Decoder;

import java.util.HashMap;

/**
 * 兴业汇收付批量代收付
 *
 * @author Cruise
 * @date 2019/3/6
 */
public class CIB03BatPayRec extends CIB03Base implements IBatPayRec {
    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        return d_BatPayRec(p_req1988);
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        return d_QryBatPayRec(p_req1998);
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return d_BatPayRec(p_req9188);
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return d_QryBatPayRec(p_req9198);
    }

    public RetAtsBatPayRec d_BatPayRec(ReqBatPayRec p_reqBat) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_reqBat.reqHeader);
        retAts.reqSeqID = p_reqBat.reqBatchNO;

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqBat.ownAct, "");
            if (actItem == null || !FileHelper.existFile(actItem.ownKeyStorePath) || !FileHelper.existFile(actItem.oppCertFilePath)) {
                retAts.respCode = "0";
                if (actItem == null) {
                    retAts.respInfo = "未找到账号" + p_reqBat.ownAct + "的批量商户配置节点";
                } else {
                    retAts.respInfo = "账号" + p_reqBat.ownAct + "的证书文件不存在";
                }
                retAts.reqSeqID = p_reqBat.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9981;
                retAts.writeRetToATS();
                return retAts;
            }
            String tmpSerialNo = "serialNo";
            String tmpValue = "value";
            String tmpRespMsg = "respMsg";
            String tmpRespCode = "respCode";
            String tmpBatchDesc = "batchDesc";
            HashMap<String, String> postMapParams = new HashMap<String, String>();
            postMapParams.put("version", "1.0.2");
            postMapParams.put("mchtId", actItem.merchantId);
            postMapParams.put("signType", "RSA");
            postMapParams.put(tmpSerialNo, p_reqBat.reqBatchNO);
            postMapParams.put("transTime", Format.DateTime14Format.format(p_reqBat.getPayDateTime()));
            postMapParams.put("count", p_reqBat.totalNum);
            postMapParams.put("gross", p_reqBat.totalAmt);

            if ("1988".equals(p_reqBat.reqHeader.transType)) {
                postMapParams.put("fileName", "batchPay.txt");
            } else {
                postMapParams.put("fileName", "batchRec.txt");
            }

            StringBuilder sbFileContent = new StringBuilder();
            sbFileContent.append(actItem.merchantId).append("|");
            sbFileContent.append(p_reqBat.reqBatchNO).append("|");
            sbFileContent.append(p_reqBat.totalNum).append("|");
            sbFileContent.append(p_reqBat.totalAmt).append("\n");

            int recordCount = 0;
            while (p_reqBat.readRecord()) {
                recordCount++;
                if (recordCount > 1) {
                    sbFileContent.append("\n");
                }
                sbFileContent.append(p_reqBat.readedDetail.askNumber).append("|");
                sbFileContent.append("").append("|");
                sbFileContent.append("").append("|");
                if ("1988".equals(p_reqBat.reqHeader.transType)) {
                    sbFileContent.append(p_reqBat.readedDetail.recAct).append("|");
                    sbFileContent.append(p_reqBat.readedDetail.recName).append("|");
                } else {
                    sbFileContent.append(p_reqBat.readedDetail.payAct).append("|");
                    sbFileContent.append(p_reqBat.readedDetail.payName).append("|");
                }

                String[] findValues = new String[2];
                if ("1988".equals(p_reqBat.reqHeader.transType)) {
                    findValues[0] = p_reqBat.readedDetail.recBankCode;
                    findValues[1] = p_reqBat.readedDetail.recAreaName;
                } else {
                    findValues[0] = p_reqBat.readedDetail.payBankCode;
                    findValues[1] = p_reqBat.readedDetail.payAreaName;
                }
                HashMap<String, String> BANK_CODE = this.getBankConfig().getMapAdvanceValues("BankCodeMapping", new String[]{"ATSBankCode", "ATSAreaName"}, new String[]{tmpValue}, findValues);
                if (BANK_CODE != null && BANK_CODE.size() > 0 && BANK_CODE.containsKey(tmpValue)) {
                    sbFileContent.append(BANK_CODE.get("value")).append("|");
                } else {
                    sbFileContent.append("|");
                }
                sbFileContent.append(p_reqBat.readedDetail.cnapsName).append("|");
                sbFileContent.append(p_reqBat.readedDetail.payAmount).append("|");
                String isPrivate = p_reqBat.readedDetail.isPrivate;
                if ("1".equals(isPrivate)) {
                    sbFileContent.append("1").append("|");
                } else {
                    sbFileContent.append("0").append("|");
                }
                sbFileContent.append(p_reqBat.readedDetail.cnapsCode).append("|");
                sbFileContent.append(p_reqBat.readedDetail.memo).append("|");
                sbFileContent.append("").append("|");
                String certType = "";
                if (StringHelper.hasAnyChar(p_reqBat.readedDetail.certType) && StringHelper.hasAnyChar(p_reqBat.readedDetail.certNum)) {
                    certType = this.convertCertTypeToBank(p_reqBat.readedDetail.certType);
                    if (StringHelper.isNullOrEmpty(certType)) {
                        certType = "0";
                    }
                }
                sbFileContent.append(certType + "," + p_reqBat.readedDetail.certNum).append("|");
                sbFileContent.append(p_reqBat.readedDetail.cellPhone).append("|");
                sbFileContent.append("");
            }
            WriteBankLogLn2("批次文件内容明文:\r\n" + sbFileContent.toString());

            String fileContent = new String(Base64.encodeBase64((DEHelper.compress(sbFileContent.toString().getBytes(getCharset())))));
            postMapParams.put("fileContent", fileContent);
            postMapParams.put("mac", generateMAC(postMapParams, actItem));

            String submitUrl = "";
            if ("1988".equals(p_reqBat.reqHeader.transType)) {
                submitUrl = "batPaySubmit";
            } else {
                submitUrl = "batRecSubmit";
            }
            String tmpStrRet = sendDataToBank(JSONUtils.map2JSON(postMapParams), submitUrl);
            if (StringHelper.hasAnyChar(tmpStrRet)) {
                if (tmpStrRet.indexOf('{') >= 0) {
                    HashMap<String, String> tmpJsonRet = JSONUtils.json2Map(tmpStrRet);

                    retAts.respCode = "0";
                    retAts.respInfo = tmpJsonRet.get(tmpRespMsg);
                    retAts.reqSeqID = tmpJsonRet.get(tmpSerialNo);

                    retAts.transState = StringHelper.joinNotEmpty("+", tmpJsonRet.get("batchStatus"), tmpJsonRet.get(tmpRespCode));
                    retAts.payInfoCode = tmpJsonRet.get(tmpRespCode);
                    if (StringHelper.hasAnyChar(tmpJsonRet.get(tmpBatchDesc)) && !"null".equals(tmpJsonRet.get(tmpBatchDesc))) {
                        retAts.respInfo = tmpJsonRet.get(tmpBatchDesc);
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "银行响应数据不合法";
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "银行响应为空";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.toString();
            WriteBankLogLn(ex);
        }

        if (retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)) {
            retAts.reqSeqID = p_reqBat.reqBatchNO;
        }

        retAts.writeRetToATS();
        return retAts;
    }

    public RetAtsQryBatPayRec d_QryBatPayRec(ReqQryBatPayRec p_reqQryBat) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_reqQryBat.reqHeader);

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqQryBat.ownAct, "");
            if (actItem == null || !FileHelper.existFile(actItem.ownKeyStorePath) || !FileHelper.existFile(actItem.oppCertFilePath)) {
                retAts.respCode = "-1";
                if (actItem == null) {
                    retAts.respInfo = "未找到账号[" + p_reqQryBat.ownAct + "]商户配置信息";
                } else {
                    retAts.respInfo = "账号[" + p_reqQryBat.ownAct + "]证书文件不存在";
                }
                retAts.writeAfterDetail();
                return retAts;
            }
            String tmpSerialNo = "serialNo";
            String tmpRespMsg = "respMsg";
            String tmpBatchDesc = "batchDesc";
            HashMap<String, String> postMapParams = new HashMap<String, String>();
            postMapParams.put("version", "1.0.2");
            postMapParams.put("mchtId", actItem.merchantId);
            postMapParams.put("signType", "RSA");
            postMapParams.put(tmpSerialNo, p_reqQryBat.reqBatchNO);
            postMapParams.put("transTime", Format.DateTime14Format.format(p_reqQryBat.getBgnDateTime()));
            postMapParams.put("mac", generateMAC(postMapParams, actItem));

            String tmpStrRet = sendDataToBank(JSONUtils.map2JSON(postMapParams), "batRecPayQuery");

            if (StringHelper.hasAnyChar(tmpStrRet)) {
                if (tmpStrRet.indexOf('{') >= 0) {
                    HashMap<String, String> tmpJsonRet = JSONUtils.json2Map(tmpStrRet);

                    String tmpRespCode = tmpJsonRet.get("respCode");
                    retAts.respCode = "0";
                    retAts.respInfo = tmpJsonRet.get(tmpRespMsg);
                    if (StringHelper.hasAnyChar(tmpJsonRet.get(tmpBatchDesc)) && !"null".equals(tmpJsonRet.get(tmpBatchDesc))) {
                        retAts.respInfo = tmpJsonRet.get(tmpBatchDesc);
                    }
                    retAts.reqSeqID = tmpJsonRet.get(tmpSerialNo);

                    if ("E0000".equals(tmpRespCode)) {
                        String batchStatus = tmpJsonRet.get("batchStatus");
                        if ("1".equals(batchStatus)) {
                            String tmpRespFileStr = tmpJsonRet.get("fileContent");
                            BASE64Decoder base64Decoder = new BASE64Decoder();
                            byte[] bi = DEHelper.uncompress(base64Decoder.decodeBuffer(tmpRespFileStr));
                            String tmpFileContentRet = new String(bi, getCharset());
                            WriteBankLogLn2("银行响应文件明文:\r\n" + tmpFileContentRet);

                            String fileDetailContent = tmpFileContentRet.substring(tmpFileContentRet.indexOf('\n') + 1);
                            String[] fileLine = fileDetailContent.split("\n");
                            for (String eachLine : fileLine) {
                                String[] values = eachLine.split("\\|");
                                if (values.length == 12) {
                                    RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                    tmpRetDetail.postScript = values[0];

                                    if ("1998".equals(p_reqQryBat.reqHeader.transType)) {
                                        tmpRetDetail.payAct = p_reqQryBat.ownAct;
                                        tmpRetDetail.recAct = values[3];
                                        tmpRetDetail.recName = values[4];
                                    } else {
                                        tmpRetDetail.recAct = p_reqQryBat.ownAct;
                                        tmpRetDetail.payAct = values[3];
                                        tmpRetDetail.payName = values[4];
                                    }
                                    tmpRetDetail.payAmount = values[7];
                                    tmpRetDetail.result = StringHelper.joinNotEmpty("+", batchStatus, values[8]);
                                    tmpRetDetail.payInfoCode = values[11];
                                    tmpRetDetail.memo = values[11];
                                    retAts.writeRetDetail(tmpRetDetail);
                                } else {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = "批次明细列数有误,本应为12,实际为:" + values.length;
                                }
                            }
                        } else {
                            retAts.transState = StringHelper.joinNotEmpty("+", batchStatus, tmpRespCode);
                            retAts.payInfoCode = tmpRespCode;
                        }
                    } else if ("E0529".equals(tmpRespCode)) {
                        //E0529--订单不存在，需再次查询，若30分钟后仍为“E0529”，则该笔订单为失败订单，
                        if (canBeNotExist(p_reqQryBat, retAts, 35)) {
                            retAts.respCode = "0";
                            retAts.transState = tmpRespCode;
                            retAts.payInfoCode = tmpRespCode;
                            retAts.respInfo = tmpJsonRet.get(tmpRespMsg);
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpJsonRet.get(tmpRespMsg);
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "银行响应数据不合法";
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "银行响应为空";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeAfterDetail();
        return retAts;
    }
}
